package cn.dslcode.spring.session.redis.config;

import cn.dslcode.common.core.string.StringUtil;
import cn.dslcode.common.web.CookieUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;

/**
 * Created by dongsilin on 2018/1/21.
 * AOp方式修改sessionId修改
 */
@Slf4j
@Component
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ModifySessionIdAspect {

    @Value("${spring.session.recognize.name}")
    private String sessionRecognizeName;

    // 后置返回通知
    @AfterReturning(
            value = "execution(* org.springframework.session.data.redis.RedisOperationsSessionRepository.createSession())",
            returning = "redisSession"// 返回参数
    )
    public void changeSessionId(Object redisSession) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String sessionId = request.getHeader(sessionRecognizeName);
        if (StringUtil.isEmpty(sessionId)) sessionId = CookieUtil.getValue(request, sessionRecognizeName);
        if(StringUtil.isEmpty(sessionId)) return;

        Field mapSessionField = redisSession.getClass().getDeclaredField("cached");
        mapSessionField.setAccessible(true);
        Object mapSession = mapSessionField.get(redisSession);
        Field mapSessionIdField = mapSession.getClass().getDeclaredField("id");
        mapSessionIdField.setAccessible(true);
        mapSessionIdField.set(mapSession, sessionId);
    }

}
